package mammuthus.slave

import com.google.inject.{Singleton, Inject}
import net.csdn.common.settings.Settings

import scala.collection.mutable
import akka.actor.{Props, ActorRef}
import mammuthus.master.Akkautil2
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import net.csdn.common.logging.Loggers
import mammuthus.tool.SystemTool
import mammuthus.protocal.RegisterAgent
import mammuthus.protocal.AgentInfo
import mammuthus.proxy.MammuthusConfControl
import mammuthus.docker.DockerClient

/**
 * 3/24/15 WilliamZhu(allwefantasy@gmail.com)
 */
@Singleton
class Slave @Inject()(conf: Settings, akkaUtil: Akkautil2, mcc: MammuthusConfControl, dc: DockerClient) {
  val logger = Loggers.getLogger(getClass)
  val actorPool = mutable.HashMap[String, mutable.ArrayBuffer[ActorRef]]()
  val name = "Worker"

  val localHost = sys.env.get("MAMMUTHUS_SLAVE_HOST") match {
    case Some(i) => i
    case None => conf.get("slave.host", SystemTool.hostName match {
      case Some(i) => i
      case None => ShellCommand.exec("cat /etc/hostname")
    })
  }

  val hostName = localHost

  val localPort = sys.env.get("MAMMUTHUS_SLAVE_PORT") match {
    case Some(i) => i.toInt
    case None => conf.get("slave.port", "5020").toInt
  }

  val (system, akkaPort) = akkaUtil.createActorSystem(localHost, localPort)
  val slaveActor = system.actorOf(Props(classOf[SlaveActor], this), name)

  val masterHosts = sys.env.get("MAMMUTHUS_MASTER_HOST") match {
    case Some(i) => i
    case None => conf.get("master.host", SystemTool.hostName match {
      case Some(i) => i
      case None => ShellCommand.exec("cat /etc/hostname")
    })
  }

  val masterPort = sys.env.get("MAMMUTHUS_MASTER_PORT") match {
    case Some(i) => i.toInt
    case None => conf.get("master.port", "5010").toInt
  }

  val systemName = conf.get("eq.actor-system.name", "mammuthus")

  val masterUrls = masterHosts.split(",").map(masterHost => s"akka.tcp://${systemName}@${masterHost}:${masterPort}/user/Master")
  val masterRef = system.actorOf(Props(classOf[MasterActorRef], this))

  val scheduler = system.scheduler
  val task = new Runnable {
    def run() {
      val ip = SystemTool.ip match {
        case Some(i) => i
        case None => List()
      }
      try {
        masterRef ! RegisterAgent(
          localHost, slaveActor,
          AgentInfo(localHost,
            ip,
            SystemTool.cpuCores,
            SystemTool.memory,
            SystemTool.disk,
            SystemTool.app,
            SystemTool.docker,
            System.currentTimeMillis()))
        SystemTool.writeFile(conf.get("mammuthus.sys_env.path","/data/1/usr/local/sys_env"),s"master.url=$masterHosts",false)
      } catch {
        case e: Exception =>
        logger.error("slave report error",e)
      }
    }
  }

  def mammuthusConf = mcc

  def dockerClient = dc

  implicit val executor = system.dispatcher

  scheduler.schedule(
    initialDelay = Duration(5, TimeUnit.SECONDS),
    interval = Duration(conf.getAsLong("mammuthus.report.interval",2l), TimeUnit.SECONDS),
    runnable = task)


}
